1 module hip.util.lifetime;
2 
3 
4 /** 
5  * Not yet complete. Need more work.
6  */
7 mixin template RefCounted()
8 {
9     private int* countPtr;
10     this(this)
11     {
12         if(countPtr != null)
13             *countPtr = *countPtr + 1;
14     }
15     void startRefCount()
16     {
17         import core.stdc.stdlib:malloc;
18         countPtr = malloc(int.sizeof);
19         *countPtr = 1;
20     }
21     ~this()
22     {
23         if(countPtr != null)
24         {
25             *countPtr = *countPtr - 1;
26             if(*countPtr == 0)
27                 dispose();
28             import core.stdc.stdlib: free;
29             free(countPtr);
30             countPtr = null;
31         }
32     }
33 }
34 
35 /**
36 *   Use this function to export 
37 */
38 enum HipExportedTargets
39 {
40     nativeScript_D = 0,
41     lua,
42     unknown,
43     count
44 }
45 
46 
47 
48 version(HipScriptingAPI)
49 {
50     /**
51     *   That may be changed to an associative array in case of slowdowns
52     */
53     private __gshared Object[][HipExportedTargets.count] _hipExportedSharedUserData;
54 
55 
56     export extern(C) void hipDestroy(Object reference, int target = HipExportedTargets.nativeScript_D)
57     {
58         for(uint i = 0; i < _hipExportedSharedUserData.length; i++)
59         {
60             if(_hipExportedSharedUserData[target][i] == reference)
61             {
62                 _hipExportedSharedUserData[target][i] = null;
63                 destroy(reference);
64             }
65         }
66     }
67 
68     /** 
69     * Guarantees that the reference won't be destroyed after some time by saving the object in the exportedSharedUserData array.
70     */
71     Object hipSaveRef(Object reference, int target = HipExportedTargets.nativeScript_D)
72     {
73         for(uint i = 0; i < _hipExportedSharedUserData.length; i++)
74         {
75             if(i >= _hipExportedSharedUserData[target].length)
76                 break;
77             else if (_hipExportedSharedUserData[target][i] is reference)
78                 return reference;
79             if(_hipExportedSharedUserData[target][i] is null)
80             {
81                 _hipExportedSharedUserData[target][i] = reference;
82                 return reference;
83             }
84         }
85         _hipExportedSharedUserData[target] ~= reference;
86         return reference;
87     }
88 
89     /**
90     *   Destroys every reference inside the target. This function is useful
91     *   for managing the destruction for the targets
92     */
93     void hipDestroyTarget(int target = HipExportedTargets.nativeScript_D)
94     {
95         for(int i = 0; i < _hipExportedSharedUserData[target].length; i++)
96         {
97             if(_hipExportedSharedUserData[target][i] is null)
98                 break;
99             hipDestroy(_hipExportedSharedUserData[target][i], target);
100         }
101     }
102 }
103 else
104 {
105     pragma(inline, true)
106     Object hipSaveRef(Object reference, int target = HipExportedTargets.nativeScript_D){return reference;}
107 }